package ar.edu.itba.it.pdc.protocol;

import ar.edu.itba.it.pdc.utils.TempFilesSetup;

public class POP3Utils {

	private final static String CRLF = TempFilesSetup.CRLF;
	
	public static String fold(int used, String s) {
		int end;
		char c;
		// Strip trailing spaces and newlines
		for (end = s.length() - 1; end >= 0; end--) {
			c = s.charAt(end);
			if (c != ' ' && c != '\t' && c != '\r' && c != '\n')
				break;
		}
		if (end != s.length() - 1)
			s = s.substring(0, end + 1);

		// if the string fits now, just return it
		if (used + s.length() <= 76)
			return s;

		// have to actually fold the string
		StringBuffer sb = new StringBuffer(s.length() + 4);
		char lastc = 0;
		while (used + s.length() > 76) {
			int lastspace = -1;
			for (int i = 0; i < s.length(); i++) {
				if (lastspace != -1 && used + i > 76)
					break;
				c = s.charAt(i);
				if (c == ' ' || c == '\t')
					if (!(lastc == ' ' || lastc == '\t'))
						lastspace = i;
				lastc = c;
			}
			if (lastspace == -1) {
				// no space, use the whole thing
				sb.append(s);
				s = "";
				used = 0;
				break;
			}
			sb.append(s.substring(0, lastspace));
			sb.append(CRLF);
			lastc = s.charAt(lastspace);
			sb.append(lastc);
			s = s.substring(lastspace + 1);
			used = 1;
		}
		sb.append(s);
		return sb.toString();
	}

	public static String unfold(String s) {
		StringBuffer sb = null;
		int i;
		while ((i = indexOfAny(s, CRLF)) >= 0) {
			int start = i;
			int l = s.length();
			i++; // skip CR or NL
			if (i < l && s.charAt(i - 1) == '\r' && s.charAt(i) == '\n')
				i++; // skip LF
			if (start == 0 || s.charAt(start - 1) != '\\') {
				char c;
				if (i < l && ((c = s.charAt(i)) == ' ' || c == '\t')) {
					i++; // skip whitespace
					while (i < l && ((c = s.charAt(i)) == ' ' || c == '\t'))
						i++;
					if (sb == null)
						sb = new StringBuffer(s.length());
					if (start != 0) {
						sb.append(s.substring(0, start));
						sb.append(' ');
					}
					s = s.substring(i);
					continue;
				}
				// it's not a continuation line, just leave it in
				if (sb == null)
					sb = new StringBuffer(s.length());
				sb.append(s.substring(0, i));
				s = s.substring(i);
			} else {
				// there's a backslash at "start - 1"
				// strip it out, but leave in the line break
				if (sb == null)
					sb = new StringBuffer(s.length());
				sb.append(s.substring(0, start - 1));
				sb.append(s.substring(start, i));
				s = s.substring(i);
			}
		}
		if (sb != null) {
			sb.append(s);
			return sb.toString();
		} else
			return s;
	}

	private static int indexOfAny(String s, String any) {
		return indexOfAny(s, any, 0);
	}

	private static int indexOfAny(String s, String any, int start) {
		try {
			int len = s.length();
			for (int i = start; i < len; i++) {
				if (any.indexOf(s.charAt(i)) >= 0)
					return i;
			}
			return -1;
		} catch (StringIndexOutOfBoundsException e) {
			return -1;
		}
	}
}
